package com.jhh.pay.heli.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.jhh.pay.heli.annotation.HeLiBaoService;
import com.jhh.pay.heli.api.PayApi;
import com.jhh.pay.heli.api.WithholdApi;
import com.jhh.pay.heli.bean.HttpWrapper;
import com.jhh.pay.heli.bean.pay.OrderPayStateHto;
import com.jhh.pay.heli.bean.pay.PayForPersonHto;
import com.jhh.pay.heli.bean.pay.SinglePayForPersonResult;
import com.jhh.pay.heli.bean.sign.PaySign;
import com.jhh.pay.heli.bean.sign.WithholdSign;
import com.jhh.pay.heli.bean.withhold.OrderWithholdStateHto;
import com.jhh.pay.heli.bean.withhold.SingleWithholdResult;
import com.jhh.pay.heli.bean.withhold.WithholdHto;
import com.jhh.pay.heli.constant.Constant;
import com.jhh.pay.heli.manager.PayHelper;
import com.jhh.pay.heli.service.HeLiPayService;
import com.jhh.pay.heli.utils.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import retrofit2.Response;

import java.util.Map;

/**
 * Created by zhangqi on 2017/12/4.
 */
@Service
public class HeLiPayServiceImpl implements HeLiPayService {

    /**
     * 网络请求Api  -- 代付相关
     */
    @HeLiBaoService
    PayApi mPayApi;

    /**
     * 网络请求Api -- 代扣相关
     */
    @HeLiBaoService
    WithholdApi mWithholdApi;

    private final Logger mLogger = LoggerFactory.getLogger(HeLiPayServiceImpl.class);

    /**
     * 代付
     * @return
     */
    public HttpWrapper<SinglePayForPersonResult> payForPerson(PayForPersonHto payForPerson, PaySign paySign){
        mLogger.info("代付的参数:"+JSONObject.toJSONString(payForPerson));
        HttpWrapper<SinglePayForPersonResult> httpWrapper = new HttpWrapper<>();
        try {
            Map<String, String> payMap = PayHelper.toSign(payForPerson,paySign.getRSA_PRIVATE());
            mLogger.info("签名后的参数: "+ JSONObject.toJSONString(payMap));
            Response<SinglePayForPersonResult> execute = mPayApi.payForPerson(payMap).execute();
            if(execute.isSuccessful()){
                SinglePayForPersonResult body = execute.body();
                mLogger.info("请求成功 200: "+JSONObject.toJSONString(body));


                httpWrapper = aboutPay(body,paySign,Constant.MD5_TYPE_PAY);

            }else{
                mLogger.info("代付请求失败");
            }

        }catch (Exception e){
            mLogger.info("支付遇到问题:"+e.toString());
            e.printStackTrace();
        }

        return httpWrapper;
    }

    /**
     * 查询代付订单状态
     * @param orderStateHto
     * @return
     */
    @Override
    public HttpWrapper<SinglePayForPersonResult> findPayOrderState(OrderPayStateHto orderStateHto, PaySign paySign) {
        mLogger.info("代付查询的参数:"+JSONObject.toJSONString(orderStateHto));
        HttpWrapper<SinglePayForPersonResult> httpWrapper = new HttpWrapper<>();
        try {
            Map<String, String> findMap = PayHelper.toSign(orderStateHto,paySign.getRSA_PRIVATE());
            Response<SinglePayForPersonResult> execute = mPayApi.findOrderState(findMap).execute();
            if(execute.isSuccessful()){
                SinglePayForPersonResult body = execute.body();
                mLogger.info("请求成功 200: "+JSONObject.toJSONString(body));
                httpWrapper = aboutPay(body,paySign,Constant.MD5_TYPE_QUERY);
            }else{
                mLogger.info("查询代付失败");
            }
        }catch (Exception e){
            mLogger.info("查询代付遇到问题:"+e.toString());
            e.printStackTrace();
        }
        return httpWrapper;
    }

    public HttpWrapper<SinglePayForPersonResult> aboutPay(SinglePayForPersonResult srs,PaySign paySign,String type){
        HttpWrapper<SinglePayForPersonResult> wrapper = new HttpWrapper<>();
        /**
         * 验签
         */
        String md5Sign = Util.PaytoMD5(srs, type,paySign.getMD5_KEY());
        mLogger.info(type+"本地签名: "+md5Sign);
        if(!srs.getSign().equals(md5Sign)){
            mLogger.info("--------------这是代付相关的-------------");
            wrapper.setCode(Constant.FAILD);
            wrapper.setInfo("验签失败");
            mLogger.info(type+"结果验签失败");
            return wrapper;
        }
        mLogger.info(type+"结果验签成功");

        //TODO  doSomething

        return wrapper;
    }

    /**
     * 单笔代扣
     * @param withholdHto
     * @param withholdSign
     * @return
     */
    @Override
    public HttpWrapper<SingleWithholdResult> withholdSingle(WithholdHto withholdHto, WithholdSign withholdSign) {
        mLogger.info("代扣的参数:"+JSONObject.toJSONString(withholdHto));
        HttpWrapper<SingleWithholdResult> httpWrapper = null;

        try {
            Map<String, String> withholdMap = PayHelper.toSign(withholdHto,withholdSign);
            Response<SingleWithholdResult> execute = mWithholdApi.withhold(withholdMap).execute();
            if(execute.isSuccessful()){
                SingleWithholdResult body = execute.body();
                mLogger.info("请求成功 200: "+JSONObject.toJSONString(body));

                httpWrapper = aboutWithhold(body,withholdSign,Constant.MD5_TYPE_WITHHOLD);
            }else{
                mLogger.info("单笔代扣失败");
            }
        }catch (Exception e){
            mLogger.info("单笔代扣遇到问题:"+e.toString());
            e.printStackTrace();
        }
        return httpWrapper;
    }

    /**
     * 查询单笔代扣
     * @param orderWithholdStateHto
     * @param withholdSign
     * @return
     */
    @Override
    public HttpWrapper<SingleWithholdResult> findWithholdOrderState(OrderWithholdStateHto orderWithholdStateHto, WithholdSign withholdSign) {
        mLogger.info("代扣查询的参数:"+JSONObject.toJSONString(orderWithholdStateHto));
        HttpWrapper<SingleWithholdResult> httpWrapper = null;
        try {
            Map<String, String> withholdOrderMap = PayHelper.toSign(orderWithholdStateHto,withholdSign);
            Response<SingleWithholdResult> execute = mWithholdApi.findWithholdOrderState(withholdOrderMap).execute();
            if(execute.isSuccessful()){
                SingleWithholdResult body = execute.body();
                mLogger.info("请求成功 200: "+JSONObject.toJSONString(body));

                httpWrapper = aboutWithhold(body,withholdSign,Constant.MD5_TYPE_QUERY_WITHHOLD);
            }else{
                mLogger.info("单笔代扣查询失败");
            }
        }catch (Exception e){
            mLogger.info("单笔代扣查询遇到问题:"+e.toString());
            e.printStackTrace();
        }
        return httpWrapper;
    }

    /**
     * 回调结果解析
     * @param body
     * @param withholdSign
     * @return
     */
    @Override
    public HttpWrapper<SingleWithholdResult> WithholdCallBackResult(SingleWithholdResult body, WithholdSign withholdSign) {
        mLogger.info("代扣回调的参数:"+JSONObject.toJSONString(body));
        HttpWrapper<SingleWithholdResult> wrapper = null;
        try {
            wrapper = aboutWithhold(body,withholdSign,Constant.MD5_TYPE_CALLBACK_WITHHOLD);
        }catch (Exception e){
            mLogger.info("代扣回调遇到问题:"+e.toString());
            e.printStackTrace();
        }

        return wrapper;
    }

    public HttpWrapper<SingleWithholdResult> aboutWithhold(SingleWithholdResult body, WithholdSign withholdSign, String type){
        HttpWrapper<SingleWithholdResult> wrapper = new HttpWrapper<>();
        String md5Sign = Util.WithholdtoMD5(body,type,withholdSign.getMD5_KEY());
        mLogger.info(type+"本地签名: "+md5Sign);
        if(!body.getSign().equals(md5Sign)){
            mLogger.info("--------------这是代扣相关的-------------");
            wrapper.setCode(Constant.FAILD);
            wrapper.setInfo("验签失败");
            mLogger.info(type+"结果验签失败");
            return wrapper;
        }
        mLogger.info(type+"结果验签成功");

        //TODO

        switch (body.getRt2_retCode()){
            case SingleWithholdResult.SUCCESS:
                wrapper.setCode(Constant.SUCCESS);
                wrapper.setData(body);
                wrapper.setInfo("交易成功");
                break;
            case SingleWithholdResult.INHAND:
                wrapper.setCode(Constant.SUCCESS);
                wrapper.setInfo("处理中");
                break;
            case SingleWithholdResult.FAILD:
                wrapper.setCode(Constant.ERROR);
                wrapper.setInfo("订单失败");
                break;
        }

        return wrapper;
    }
}
